﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using Samurai.Client.Commands;
using Samurai.DAL;
using Samurai.Infrastructure;

namespace Samurai.Client.DataContexts
{
    public class MoviesDataContext : ADataContext
    {
        private Activity _currentActivity;
        public Activity CurrentActivity
        {
            get { return _currentActivity; }
            set
            {
                _currentActivity = value;
                OnPropertyChanged("CurrentActivity");
            }
        }

        private GenreItem _selectedGenreItem;
        public GenreItem SelectedGenreItem
        {
            get { return _selectedGenreItem; }
            set
            {
                _selectedGenreItem = value;
                OnSelectedGenreItemPropertyChanged();
            }
        }

        private void OnSelectedGenreItemPropertyChanged()
        {
            //if (base.PropertyChanged != null)
            //    base.PropertyChanged(this, new PropertyChangedEventArgs("SelectedGenreItem"));
            base.OnPropertyChanged("SelectedGenreItem");
            ShowByGenreCommand.Execute(_selectedGenreItem.Text);

        }

        private static MoviesDataContext _instance;
        public static MoviesDataContext Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new MoviesDataContext();
                return _instance;
            }
        }

        public ExitCommand ExitCommand { get; set; }

        public OpenDirectoryCommand OpenDirectoryCommand { get; set; }
        public RefreshMoviesCommand RefreshMoviesCommand { get; set; }

        public ShowRepositoryCommand ShowRepositoryCommand { get; set; }

        public ShowByGenreCommand ShowByGenreCommand { get; set; }

        public SearchCommand SearchCommand { get; set; }

        public GotoUrlCommand GotoUrlCommand { get; set; }

        public ExportCommand ExportCommand { get; set; }

        public CommandBase ImportCommand { get; set; }

        public EditMovieCommand EditMovieCommand { get; set; }

        public NotAMovieCommand NotAMovieCommand { get; set; }

        public string[] GroupingCategories { get; set; }

        private string _selectedGroupingCategory;
        public string SelectedGroupingCategory
        {
            get
            {
                return _selectedGroupingCategory;
            }
            set
            {
                _selectedGroupingCategory = value;
                base.OnPropertyChanged("SelectedGroupingCategory");
            }
        }

        public static readonly GenreItem AllItem = new GenreItem { Text = "All", Image = "pack://application:,,,/Samurai.Client;component/Images/all_movies_48x48.gif" };

        private MoviesDataContext()
        {
            Genres = new ObservableCollection<GenreItem>(new[] { AllItem });

            Movies = new ObservableCollection<Movie>();

            ExitCommand = new ExitCommand();

            OpenDirectoryCommand = OpenDirectoryCommand.Instance;
            RefreshMoviesCommand = new RefreshMoviesCommand(Movies, Genres);

            ShowRepositoryCommand = new ShowRepositoryCommand();

            GotoUrlCommand = new GotoUrlCommand();

            ShowByGenreCommand = new ShowByGenreCommand(Movies);

            SearchCommand = new SearchCommand(Movies);

            ExportCommand = new ExportCommand(Movies);

            ImportCommand = new ImportCommand(Movies);

            EditMovieCommand = new EditMovieCommand();

            NotAMovieCommand = new NotAMovieCommand(Movies, Genres);

            TakeLongOperationAction(ImportCommand);
            TakeLongOperationAction(RefreshMoviesCommand);
            TakeLongOperationAction(NotAMovieCommand);

            CrawlDirectoryCommand.Instance.CandidateMovieFound = CandidateMovieFound;
            CrawlDirectoryCommand.Instance.DirectoryCrawlComplete = DirectoryCrawlComplete;
            CreateMovieCommand.Instance.MovieCreated = MovieCreated;
            CreateMovieCommand.Instance.MovieCreationInterrupted = MovieCreationInterrupted;
            CreateMovieCommand.Instance.MovieCreationCompleted = MovieCreationCompleted;

        }

        private bool MovieCreationCompleted(int movieCount)
        {
            CurrentActivity = new Activity { Mode = ActivityMode.NoAction, Details = string.Format("{0} movie summary created", movieCount) };
            return true;
        }

        private void MovieCreationInterrupted()
        {
            CurrentActivity = new Activity { Mode = ActivityMode.NoAction, Details = "Movie information extraction halted! !" };
        }

        public bool CandidateMovieFound(CandidateMovie movie)
        {
            CurrentActivity = new Activity() { Mode = ActivityMode.Crawling, Details = movie.Path };

            return true;
        }

        public bool DirectoryCrawlComplete(int directoryCount)
        {
            CurrentActivity = new Activity() { Mode = ActivityMode.Crawling, Details = string.Format("{0} directories found.", directoryCount) };

            return true;
        }

        public bool MovieCreated(Movie movie)
        {
            CurrentActivity = new Activity() { Mode = ActivityMode.Fetching, Details = movie.Title };

            return true;
        }

        public ObservableCollection<GenreItem> Genres { get; set; }

        public ObservableCollection<Movie> Movies { get; set; }

        public ObservableCollection<GroupedMovie> GroupedMovies { get; set; }

        public override void OnLoaded()
        {
            InitializeGenres();

            SelectedGenreItem = Genres[0];
            CrawlDirectoryCommand.Instance.Execute(null);
        }

        private void InitializeGenres()
        {
            var newGenres = Manager.Instance.GetNewGenres(Genres);

            foreach (var genreItem in newGenres)
            {
                Genres.Add(genreItem);
            }
        }
    }
}